﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace aerowan.common.Network
{
    public class NetworkServer
    {
        public IPAddress Address { get; private set; }
        public int Port { get; private set; }

        public Socket ServerSocket { get; private set; }

        public List<NetConnection> Clients { get; private set; }

        public NetworkServer(IPAddress address, int port)
        {
            Address = address;
            Port = port;
            Clients = new List<NetConnection>();
        }

        public void Start()
        {
            ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ServerSocket.Bind(new IPEndPoint(Address, Port));
            Console.WriteLine("NetworkServer listening on " + Address.ToString() + ":" + Port);
            ServerSocket.Listen(100);
            BeginAccept();
        }

        void RegisterClient(NetConnection client)
        {
            lock (Clients)
            {
                Clients.Add(client);
            }
        }

        void UnregisterClient(NetConnection client)
        {
            lock (Clients)
            {
                Clients.Remove(client);
            }
        }

        void BeginAccept()
        {
            ServerSocket.BeginAccept(new AsyncCallback(EndAccept), null);
        }

        void EndAccept(IAsyncResult ar)
        {
            Socket clientSocket = ServerSocket.EndAccept(ar);
            if (clientSocket != null || clientSocket.Connected)
            {
                NetConnection connection = new NetConnection(clientSocket);
                RegisterClient(connection);
                connection.Closed += new NetConnection.NetConnectionClosedEventHandler(() =>
                {
                    UnregisterClient(connection);
                });
            }
            BeginAccept();
        }
    }
}
